package com.jsoft.service;

import com.jsoft.dto.DiscountDto;
import com.jsoft.dto.OrderDto;
import com.jsoft.dto.OrderItemDto;
import com.jsoft.dto.ServiceDto;
import com.jsoft.manager.*;
import com.jsoft.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Date: 05.09.13
 * Time: 11:48
 */

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderManager orderManager;
    @Autowired
    private PlaceManager placeManager;
    @Autowired
    private ServicesManager servicesManager;
    @Autowired
    private DiscountManager discountManager;
    @Autowired
    private OrderItemManager orderItemManager;
    @Autowired
    private MenuItemManager menuItemManager;

    @Override
    @Transactional
    public Integer createOrder(Integer placeId) {
        PlaceDao placeDao = placeManager.getById(placeId);
        OrderDao orderDao = new OrderDao();
        orderDao.setPlace(placeDao);
        orderManager.create(orderDao);
        return orderDao.getObjectId();
    }

    @Override
    @Transactional
    public void addOrderItemsToOrder(Integer orderId, OrderItemDto... items) {
        if (items.length != 0) {
            OrderDao order = orderManager.getById(orderId);
            List<Integer> ids = new ArrayList<Integer>();
            for (OrderItemDto dto : items) {
                ids.add(dto.getMenuItem().getId());
            }
            List<MenuItemDao> menuItemList = menuItemManager.getByIds(ids.toArray(new Integer[items.length]));
            List<OrderItemDao> orderItemList = new ArrayList<OrderItemDao>();
            for (OrderItemDto item : items) {
                OrderItemDao dao = new OrderItemDao();
                for (MenuItemDao menuItem : menuItemList) {
                    if (item.getMenuItem().getId().equals(menuItem.getObjectId())) {
                        dao.setMenuItem(menuItem);
                        break;
                    }
                }
                dao.setComment(item.getComment());
                dao.setCount(item.getCount());
                orderItemList.add(dao);
            }
            order.setOrderItemList(orderItemList);
            orderManager.update(order);
        }
    }

    @Override
    @Transactional
    public void setClientCountToOrder(Integer orderId, Integer clientCount) {
        OrderDao order = orderManager.getById(orderId);
        order.setClientCount(clientCount);
        orderManager.update(order);
    }

    @Override
    @Transactional
    public void addServiceToOrder(Integer orderId, ServiceDto... services) {
        OrderDao order = orderManager.getById(orderId);
        List<Integer> ids = new ArrayList<Integer>();
        for (ServiceDto dto : services) {
            ids.add(dto.getObjectId());
        }
        List<ServiceDao> serviceDaoList = servicesManager.getByIds(ids.toArray(new Integer[ids.size()]));
        order.setServiceList(serviceDaoList);
        orderManager.update(order);
    }

    @Override
    @Transactional
    public void addDiscountsToOrder(Integer orderId, DiscountDto... discounts) {
        OrderDao order = orderManager.getById(orderId);
        List<Integer> ids = new ArrayList<Integer>();
        for (DiscountDto dto : discounts) {
            ids.add(dto.getId());
        }
        List<DiscountMarginDao> discountDaoList = discountManager.getByIds(ids.toArray(new Integer[ids.size()]));
        order.setDiscountList(discountDaoList);
        orderManager.update(order);
    }

    @Override
    @Transactional
    public void addDiscountsToOrderItem(Integer orderItemId, DiscountDto... discounts) {
        OrderItemDao orderItem = orderItemManager.getById(orderItemId);
        List<Integer> ids = new ArrayList<Integer>();
        for (DiscountDto dto : discounts) {
            ids.add(dto.getId());
        }
        List<DiscountMarginDao> discountDaoList = discountManager.getByIds(ids.toArray(new Integer[ids.size()]));
//        orderItem.setDiscountList(discountDaoList);
        orderItemManager.update(orderItem);
    }

    @Override
    @Transactional
    public OrderDto recountOrder(Integer orderId/*, OrderItemDto... items*/) {
        //Заказываем все дозаказанные блюда
    //    addOrderItemsToOrder(orderId, items);
        //Достаем заказ
        OrderDao orderDao = orderManager.getById(orderId);
        //Достаем скидки заказа (шапка)
        List<DiscountMarginDao> orderDiscountList = orderDao.getDiscountList();
        //Достаем заказанные блюда у заказа
        List<OrderItemDao> orderItemList = orderDao.getOrderItemList();

        // Считаем общую сумму заказа
        BigDecimal orderAmount = new BigDecimal("0");
        for (OrderItemDao orderItem : orderItemList) {
            //Получаем скидки и применяем
            List<DiscountMarginDao> discountDaoList = orderItem.getMenuItem().getDiscountList();
            BigDecimal discountVal = new BigDecimal("0");
            if (discountDaoList.size() != 0) {
                for (DiscountMarginDao discount : discountDaoList) {
                    BigDecimal value = discount.getPercent() ?
                            orderItem.getMenuItem().getPrice().divide(new BigDecimal("100")).multiply(discount.getDiscountValue()) :
                            discount.getDiscountValue();
                    discountVal = discountVal.add(value);
                }
            }
            orderAmount = orderAmount.add(orderItem.getMenuItem().getPrice().subtract(discountVal));
        }

        //Достаем сервисы у заказа
        List<ServiceDao> serviceList = orderDao.getServiceList();
        // Добавляем к заказу сумму всех сервисов
        BigDecimal serviceValue = new BigDecimal("0");
        if (serviceList.size() != 0) {
            for (ServiceDao service : serviceList) {
                serviceValue = serviceValue.add(service.getValue());
            }
        }
        orderAmount = orderAmount.add(serviceValue);
        OrderDto orderDto = orderDao.wrapOrderDto();
        orderDto.setOrderAmount(orderAmount);
        return orderDto;
    }
}
